import { Application } from 'egg';

import { oa, ns, getCache, setCache, delCache } from './itf';
import { uuid, touint } from '@mac-xiang/method';

function getNode(node: undefined | ns | ns[]) {
  const r: string[] = [];
  let t: ns[] = [];

  if (Array.isArray(node)) {
    t = node;
  } else if (typeof node == "string") {
    node.split(".").forEach(a => {
      if (a.length) { t.push(a); }
    });
  } else if (typeof node == "number") {
    t.push(node);
  }
  t.forEach(a => { r.push(a.toString()); });
  return r;
}

export class TmkCache {
  // _tmkCacheSign = "";
  app: Application;
  constructor (app: Application) {
    this.app = app;
    // this.app.messenger.once("_tmkSetCacheSign", (r: any) => {
    //   if (typeof r == "string" && r.length) {
    //     this._tmkCacheSign = r;
    //   }
    // });
  }
  /** 获取全局缓存
   * @param node string|string[] 节点
   */
  getCache(node: undefined | ns | ns[], method?: number) {
    return new Promise<oa>(resolve => {
      // if (!n.length) return resolve({ err: "参数错误", raw: node });
      const s: getCache = {
        pid: process.pid,
        sign: uuid,
        path: getNode(node),
        method: touint(method)
      };
      this.app.messenger.once(s.sign, resolve);
      this.app.messenger.sendToAgent("_tmkGetCache", s);
    });
  }
  setCache(node: ns | ns[], data: any, push?: any) {
    return new Promise<boolean>((resolve) => {
      const s: setCache = {
        pid: process.pid,
        sign: uuid,
        path: getNode(node),
        value: data,
        push: push
      };
      this.app.messenger.once(s.sign, resolve);
      this.app.messenger.sendToAgent("_tmkSetCache", s);
    });
  }
  delCache(node: ns | ns[], pop?: any) {
    return new Promise<any>((resolve) => {
      const s: delCache = {
        pid: process.pid,
        sign: uuid,
        path: getNode(node),
        pop: pop
      };
      if (s.path.length) {
        this.app.messenger.once(s.sign, resolve);
        this.app.messenger.sendToAgent("_tmkDelCache", s);
      } else resolve(false);
    });
  }
  async getHistory(node: undefined | ns | ns[], method?: number) {
    const path = getNode(node);
    path.unshift("_tmkTimeData");
    return await this.getCache(path, method);
  }
  async setHistory(node: ns | ns[], data: any, push?: any) {
    const path = getNode(node);
    if (!path.length) return false;
    else if (path.length == 1) {
      if (!(data && Array.isArray(data.rooms))
      ) {
        return false;
      }
    }
    path.unshift("_tmkTimeData");
    return await this.setCache(path, data, push);
  }
  async delHistory(node: ns | ns[], pop?: any) {
    const path = getNode(node);
    if (!path.length) return false;
    path.unshift("_tmkTimeData");
    return await this.delCache(path, pop);
  }
}

export default (app: Application) => {
  app.cache = new TmkCache(app);
};
